package com.dhecp.project.quartz.service.impl;

import com.alibaba.fastjson.JSON;
import com.dhecp.common.utils.MessageUtils;
import com.dhecp.common.utils.RandomValueUtils;
import com.dhecp.common.utils.StringUtils;
import com.dhecp.core.constant.FlowableConstant;
import com.dhecp.framework.util.ShiroUtils;
import com.dhecp.project.business.domain.FbaPlanOrder;
import com.dhecp.project.business.domain.LogisticsMmodeGrads;
import com.dhecp.project.business.domain.ProductActiveComponent;
import com.dhecp.project.business.mapper.FbaPlanOrderMapper;
import com.dhecp.project.business.mapper.ProductActiveMapper;
import com.dhecp.project.common.domain.ModuleNidAndBid;
import com.dhecp.project.common.mapper.ModuleNidAndBidMapper;
import com.dhecp.project.finance.mapper.PartnerBookedApplyMapper;
import com.dhecp.project.flowable.domain.ActRuntimeInstance;
import com.dhecp.project.flowable.mapper.ActProcessMapper;
import com.dhecp.project.flowable.mapper.SysProcessInstanceMapper;
import com.dhecp.project.hr.domain.OperateCompanyApply;
import com.dhecp.project.hr.domain.OperateCompanyRatio;
import com.dhecp.project.hr.domain.OperateCompanyRoute;
import com.dhecp.project.hr.mapper.OperateCompanyApplyMapper;
import com.dhecp.project.hr.mapper.OperateCompanyRatioMapper;
import com.dhecp.project.hr.mapper.OperateCompanyRouteMapper;
import com.dhecp.project.logstics.mapper.LogsticsMmodeGradsMapper;
import com.dhecp.project.purchase.domain.PurchasePlan;
import com.dhecp.project.purchase.mapper.PurchasePlanMapper;
import com.dhecp.project.storage.domain.*;
import com.dhecp.project.storage.mapper.*;
import com.dhecp.project.storage.service.DeliveryLogisticsService;
import com.dhecp.project.system.domain.SysDepotInfo;
import com.dhecp.project.system.domain.SysUserInfo;
import com.dhecp.project.system.mapper.SysDepotInfoMapper;
import com.dhecp.project.system.service.SysApiLogService;
import com.dhecp.project.system.service.SysUserInfoService;
import liquibase.pro.packaged.A;
import org.flowable.engine.HistoryService;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.runtime.ProcessInstance;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.dhecp.common.core.domain.AjaxResult;
import com.dhecp.project.quartz.mapper.SysJobCommonMapper;
import com.dhecp.project.quartz.service.SysJobCommonService;
import sun.security.krb5.internal.PAData;

import javax.xml.crypto.Data;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 定时任务通用调用方法（调用目标字符串） 服务层
 *
 * @author DH-Xxj
 * @version 2020年11月25日
 */
@Service
public class SysJobCommonServiceImpl implements SysJobCommonService {

    @Autowired
    private SysJobCommonMapper jobCommonMapper;
    @Autowired
    private PurchaseStorageMapper storageMapper;
    @Autowired
    private ProductAssembleMapper assembleMapper;
    @Autowired
    private PurchasePlanMapper purchasePlanMapper;
    @Autowired
    private ProductActiveMapper productActiveMapper;
    @Autowired
    private ModuleNidAndBidMapper moduleNidAndBidMapper;
    @Autowired
    private SysUserInfoService userInfoService;
    @Autowired
    private AssemblyMaintainMapper maintainMapper;
    @Autowired
    private OperateCompanyRatioMapper ratioMapper;
    @Autowired
    private OperateCompanyApplyMapper applyMapper;
    @Autowired
    private OperateCompanyRouteMapper operateCompanyRouteMapper;
    @Autowired
    private PartnerBookedApplyMapper partnerBookedApplyMapper;//汇款数
    @Autowired
    private ActProcessMapper actProcessMapper;
    @Autowired
    private FbaPlanOrderMapper fbaPlanOrderMapper;
    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private HistoryService historyService;
    @Autowired
    private SysProcessInstanceMapper sysProcessInstanceMapper;
    @Autowired
    private DeliveryLogisticsService deliveryLogisticsService;
    @Autowired
    private DeliveryLogisticsMapper deliveryLogisticsMapper;
    @Autowired
    private SysApiLogService sysApiLogService;
    @Autowired
    private HwStorageHistoryMapper hwStorageHistoryMapper;
    @Autowired
    private HwStorageMapper hwStorageMapper ;
    @Autowired
    private SysDepotInfoMapper sysDepotInfoMapper;
    @Autowired
    private LogsticsMmodeGradsMapper logsticsMmodeGradsMapper;


    /**
     * 数据库可执行定时任务通用调用方法
     *
     * @param callingMethod 可执行SQL语句字符串
     * @return
     * @author DH-Xxj
     */
    @Override
    public AjaxResult jobCommonCallingMethod(String callingMethod) {
        jobCommonMapper.JobCommonCallingMethod(callingMethod);
        return AjaxResult.success("操作成功");
    }


    /**
     * @Description: 定时生成组装单
     * @Param: [callingMethod]
     * @return: com.dhecp.common.core.domain.AjaxResult
     * @Author: hlf
     * @date: 2022-12-30 14:24
     */
    @Override
    public AjaxResult createProductAssemble() {
        List<PurchaseStorage> purchaseStorageList = storageMapper.getStateData();//查询 未生成组装单且已入库的数据
        for (PurchaseStorage item : purchaseStorageList
        ) {
            List<PurchaseStorage> purchaseStorages = storageMapper.selectPlanID(item.getPlanID());//判断是否还有未入库的计划
            if (purchaseStorages.size() == 0) {
                List<PurchaseStorage> storages = storageMapper.selectPlanID2(item.getPlanID());//根据计划单号获取入库单数据
                Map<String, Object> params2 = new HashMap<String, Object>();//获取NID,BID
                params2.put("moduleTable", "TCC_PRODUCTASSEMBLE");
                params2.put("entity", new PurchaseStorage()); //用于获取实体属性名取代对应字典字段名，解决大小写敏感问题
                ModuleNidAndBid moduleNidAndBid = moduleNidAndBidMapper.findModuleNidAndBid(params2);

                SysUserInfo sysUserInfo = userInfoService.queryByUserId(storages.get(0).getAuditor());

                for (PurchaseStorage item2 : storages
                ) {
                    ProductAssemble productAssemble = new ProductAssemble();//生成新的组装单
                    PurchasePlan purchasePlan = purchasePlanMapper.findByBID(item2.getPlanID());//获取采购订单

                    List<ProductActiveComponent> productActiveComponent = new ArrayList<>();
                    productActiveComponent = productActiveMapper.queryProductActiveComponentByCode(item2.getsCode());

                    AssemblyMaintain assemblyMaintain = new AssemblyMaintain(); //获取组装方案
                    assemblyMaintain = maintainMapper.findByProductID(item2.getpCode());

                    //获取用户信息
                    if (assemblyMaintain != null && productActiveComponent.size() > 0) {
                        productAssemble.setBid(moduleNidAndBid.getBid());
                        productAssemble.setNid(moduleNidAndBid.getNid());
                        productAssemble.setGuid(RandomValueUtils.getGUID());
                        productAssemble.setCreateTime(new Date());
                        productAssemble.setCid(sysUserInfo.getCid());
                        productAssemble.setCidName(sysUserInfo.getCidName());
                        productAssemble.setbUser(sysUserInfo.getUserId());
                        productAssemble.setbUserName(sysUserInfo.getUserName());
                        productAssemble.setbDept(sysUserInfo.getDeptId());
//                        productAssemble.setbDeptName(sysUserInfo.getbDeptName());
//                        productAssemble.setaUser(sysUserInfo.getaUser());
//                        productAssemble.setaUserName(sysUserInfo.getaUserName());
//                        productAssemble.setaDept(sysUserInfo.getaDept());
//                        productAssemble.setaDeptName(sysUserInfo.getaDeptName());
//                        productAssemble.setaPosition(sysUserInfo.getPositionName());
//                        productAssemble.setbPosition(sysUserInfo.getbPosition());

                        productAssemble.setProductName(purchasePlan.getSpMc());//商品名称
                        productAssemble.setProductID(purchasePlan.getSpBm());//商品编号
                        productAssemble.setvBz(productActiveComponent.get(0).getNum().toString());//商品数量
                        productAssemble.setfNSKU(item2.getfNSKU());//FNSKU
                        productAssemble.setPlanID(item2.getPlanID());//采购计划单号
                        productAssemble.setPlanNum(purchasePlan.getSpSl());//计划组装数量
                        productAssemble.setProductNameCn(item2.getName());//商品品名(中文)
                        productAssemble.setProductNameEn(item2.getName());//商品品名(英文)

                        productAssemble.setaName(assemblyMaintain.getName());//组装方案
                        productAssemble.setaWay(assemblyMaintain.getWay());//组装方式
                        productAssemble.setLength(assemblyMaintain.getLength());//长度(CM)
                        productAssemble.setWidth(assemblyMaintain.getWidth());//宽度
                        productAssemble.setHeight(assemblyMaintain.getHeight());//高度
                        productAssemble.setWeight(assemblyMaintain.getWeight());//重量

                        productAssemble.setSonStorageID(item2.getBid());//采购入库单号
                        productAssemble.setSonOrderID(item2.getOrderID());//采购订单单号
                        productAssemble.setSonProductID(item2.getsCode());//子商品编码
                        productAssemble.setSonProductName(item2.getsName());//子商品名称

//                productAssemble.setSonFNSKU(item.getName());//子FNSKU
                        productAssemble.setSonCode(item2.getsCode());//子件编码
                        productAssemble.setSonName(item2.getsName());//子件名称
                        productAssemble.setSonNum(item2.getsNum());//子件采购总数

                        productAssemble.setsPrice(productActiveComponent.get(0).getbPrice());//子件采购单价
                        productAssemble.setRkBid(item2.getBid());//入库Bid
                        productAssemble.setRkGuid(item2.getGuid());//入库Guid
                        productAssemble.setvGsBm(item2.getvGsBm());//公司编码
                        productAssemble.setvGsJc(item2.getvGsJc());//公司简称
                        productAssemble.setvGsMc(item2.getvGsMc());//公司名称
                        productAssemble.setdRkSj(item2.getUpdateTime());//入库时间
                        productAssemble.setSonUseTotal(0);//子件使用数量
//                productAssemble.setSonBalance(item.getName());//子件组装剩余总数
//                productAssemble.setSonActualBalance(item.getName());//子件实际剩余总数
                        productAssemble.setState("未上架");//状态 未上架/已上架/质检退回

                        //原始货位信息
                        productAssemble.setvHw(item2.getGoodsAllocation());//库区
                        productAssemble.setvKq(item2.getGoodsArea());//货位
                        productAssemble.setgDepot(item2.getWarehouseAddress());//所在仓库

                        item2.setAssemblyPlan(assemblyMaintain.getName());
                        storageMapper.update(item2);

                        assembleMapper.insert(productAssemble);


                    }
                }
            }
        }

        return AjaxResult.success("操作成功");
    }


    /**
     * @Description: 定时维护入库单组装方案
     * @Param: [callingMethod]
     * @return: com.dhecp.common.core.domain.AjaxResult
     * @Author: hlf
     * @date: 2022-12-30 14:24
     */
    @Override
    public AjaxResult updateAssemblyMaintain() {
        List<PurchaseStorage> purchaseStorageList = storageMapper.getNoAssmbly();//查询 未生成组装单且已入库的数据
        for (PurchaseStorage item : purchaseStorageList
        ) {
            AssemblyMaintain assemblyMaintain = new AssemblyMaintain(); //获取组装方案
            assemblyMaintain = maintainMapper.findByProductID(item.getCode());
            if (assemblyMaintain != null) {
                item.setAssemblyPlan(assemblyMaintain.getName());
                storageMapper.update(item);
            }
        }
        return AjaxResult.success("操作成功");
    }


    /**
     * @Description: 定时维护运营比例
     * @Param: [callingMethod]
     * @return: com.dhecp.common.core.domain.AjaxResult
     * @Author: hlf
     * @date: 2022-12-30 14:24
     */
    @Override
    public AjaxResult updateOperateCompanyRatio() {
        Map<String, Object> params2 = new HashMap<String, Object>();
        double jcBl;//基础比例
        try {

            OperateCompanyRatio operateCompanyRatio = ratioMapper.ratioTop1();
            //基础比例
            if (operateCompanyRatio != null) {
                jcBl = operateCompanyRatio.getvJcBl2() > 0 ? operateCompanyRatio.getvJcBl2() : 0;//获取基础比例

                List<OperateCompanyRatio> operateCompanyRatios = ratioMapper.select(params2);//获取比例设置

                List<OperateCompanyApply> operateCompanyApplies = applyMapper.queryCompanyList();//获取运营公司数据

                //获取每家公司对应的店铺数
                List<Map<String, String>> companyTier2 = operateCompanyRouteMapper.getCompanyTier2();


                for (OperateCompanyApply item : operateCompanyApplies
                ) {
                    OperateCompanyRoute operateCompanyRoute = operateCompanyRouteMapper.findByGsBm(item.getvGsBm());

                    if (item.getIsRatio().equals("1")) {//判断是否绩效公司

                        //获取回款数(回款金额
//                        double hks = partnerBookedApplyMapper.getAmountCashed(item.getvGsBm());
                        //获取店铺数
//                        int vSum = operateCompanyRouteMapper.getCompanyTier(item.getvGsBm());
                        int vSum = 0;
                        String gs = "0";
                        for (Map<String, String> cs : companyTier2
                        ) {
                            if (cs.get("VGsBm").equals(item.getvGsBm())) {
                                gs = String.valueOf(cs.get("FGsSl"));
                            }
                        }
                        vSum = Integer.parseInt(gs);

                        for (OperateCompanyRatio ratio : operateCompanyRatios
                        ) {
                            if (ratio.getvWay().equals("回款数")) {
//                                if (hks > 0 && jcBl >= ratio.getvJcBl()) {
//                                    int count = (int) (Math.log10(hks) / Math.log10(ratio.getvHkBl())) - 1;//计算符合条件的次数
//                                    if (count > 0) {
//                                        jcBl = jcBl + ratio.getvRule() * count;//添加对应的上升比例
//                                    }
//                                    //当回款比例大于回款上升区间的是取最大值
//                                    jcBl = jcBl > ratio.getvJcBl2() ? ratio.getvJcBl2() : jcBl;
//                                }

                            } else if (ratio.getvWay().equals("店铺数")) {
                                if (vSum > 0 && jcBl >= ratio.getvJcBl()) {
                                    int count = (int) (Math.log10(vSum) / Math.log10(ratio.getvDpFdBl())) - 1;//计算符合条件的次数
                                    if (count > 0) {
                                        jcBl = jcBl + ratio.getvRule() * count;//添加对应的上升比例
                                    }
                                    //当店铺数比例大于店铺数上升区间的是取最大值
                                    jcBl = jcBl > ratio.getvJcBl2() ? ratio.getvJcBl2() : jcBl;
                                }
                            }
                        }
                        //先保存运营比例
                        operateCompanyRoute.setvYyBl(jcBl);
                        //判断基础比例和特殊比例 取最大值
                        jcBl = jcBl > operateCompanyRoute.getvTsBl() ? jcBl : operateCompanyRoute.getvTsBl();
                        operateCompanyRoute.setvJcBl(jcBl);
                        operateCompanyRouteMapper.updateRoute(operateCompanyRoute);
                    }


                }
                return AjaxResult.success("操作成功");
            } else {
                return AjaxResult.error("请先设置基础比例");
            }
        } catch (Exception e) {
            return AjaxResult.error(String.valueOf(e));
        }
    }


    /**
     * @Description: 定时删除任务
     * @Param: []
     * @return: com.dhecp.common.core.domain.AjaxResult
     * @Author: fxz
     * @date: 2023-02-23 14:36
     */
    @Override
    public AjaxResult deleteTask() {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("assignee", "admin");
        List<ActRuntimeInstance> actRuntimeProcess = actProcessMapper.findActRuntimeProcess(params);
        FbaPlanOrder fbaPlanOrder;
        for (ActRuntimeInstance actRuntimeInstance : actRuntimeProcess) {
            if (actRuntimeInstance.getProcDefName().equals("头程计划单")) {
                params.put("nid", actRuntimeInstance.getTableDataId());
                fbaPlanOrder = fbaPlanOrderMapper.selectFirstRecordByNid(params);
                if (fbaPlanOrder == null) {
                    String procInstId = actRuntimeInstance.getProcInstId();
                    if (procInstId != null && !"".equals(procInstId)) {
                        if (StringUtils.isEmpty(procInstId)) {
                            return AjaxResult.error(MessageUtils.message("module.error.paramfail", procInstId));
                        }
                        ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId(procInstId).singleResult();
                        if (pi == null) {
                            return AjaxResult.error(MessageUtils.message("flowable.process.error.instanceobjectfail"));
                        }
                        runtimeService.deleteProcessInstance(pi.getId(), FlowableConstant.DELETE_PRE + "单据级联删除");
                        historyService.deleteHistoricProcessInstance(pi.getId());
                        sysProcessInstanceMapper.deleteSysProcessInstanceByGuid(pi.getBusinessKey());
                        //插入指定单据流转各环节审批人记录（单据删除记录）
                        Map<String, Object> flowRecord = new HashMap<String, Object>();
                        flowRecord.put("moduleTable", "TP_FBAPLANORDER");
                        flowRecord.put("nid", actRuntimeInstance.getTableDataId());
                        flowRecord.put("activeFlowOld", "FlowZd");
                        flowRecord.put("procInstId", procInstId);
                        flowRecord.put("createUser", "admin");
                        flowRecord.put("createUserName", "系统管理员");
                        flowRecord.put("updateUsers", "实际删除操作人： " + "系统管理员" + "【" + "admin" + "】");
                        flowRecord.put("optType", "delete");
                        sysProcessInstanceMapper.insertProcessInstanceFlowRecord(flowRecord);
                    }
                }
            }
        }
        return AjaxResult.success("操作成功");
    }


    /**
     *@Description: 定时海外仓入库任务
     *@Param: []
     *@return: com.dhecp.common.core.domain.AjaxResult
     *@Author: fxz
     *@date: 2023-12-18 14:36
     */
    @Override
    public AjaxResult stockInJob() {
        //查询已发货未入库数据
        Map<String, Object> params = new HashMap<>();
        params.put("stateName","已发货");
        params.put("stateRkName1","未入库");
        List<DeliveryLogistics> select = deliveryLogisticsMapper.select(params);
        for (DeliveryLogistics deliveryLogistics : select){
            if (deliveryLogistics.getStateRkName().equals("未入库")){
                try {
                    AjaxResult ajaxResult = deliveryLogisticsService.stockIn(deliveryLogistics.getBid(), "精品1区");
                    if (ajaxResult.get("code").equals(500)){
                        sysApiLogService.addApiLog("WMS", "stockInJob", "对接海外仓入库详情接口,postParams：" + JSON.toJSONString(deliveryLogistics.getOverseasStockInNo()), "", 500, ajaxResult.get("msg").toString());
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        return AjaxResult.success("操作成功");
    }

    /**
     *@Description: 定时海外仓库存历史
     *@Param: []
     *@return: com.dhecp.common.core.domain.AjaxResult
     *@Author: fxz
     *@date: 2023-12-18 14:36
     */
    @Override
    public AjaxResult addHwStorageHistory() {
        try {
            List<LogisticsMmodeGrads> logisticsMmodeGradList = null;
            Date now = new Date();
            //全部数量不为0
            List<HwStorage> hwStorageList = hwStorageMapper.productNumAllIsNull();
            HwStorageHistory hwStorageHistory;
            for (HwStorage hwStorage : hwStorageList){
                hwStorageHistory = new HwStorageHistory();
                BeanUtils.copyProperties(hwStorage,hwStorageHistory);
                hwStorageHistory.setGuid(RandomValueUtils.getGUID());
                hwStorageHistory.setCreatetime(now);
                hwStorageHistory.setUpdatetime(now);

                //查询仓库编码
                SysDepotInfo sysDepotInfo = sysDepotInfoMapper.findDepotInfoByDepotName(hwStorage.getGdepot());
                BigDecimal storageCharge = BigDecimal.ZERO;
                BigDecimal unitPrice = BigDecimal.ZERO;
                List<LogisticsMmodeGrads> tdjzPrice = null;
                if (sysDepotInfo != null){
                    //获取物流名称详情
                    Map<String, Object> params2 = new HashMap<String, Object>();
                    params2.put("logisticsMmodeGuid",sysDepotInfo.getGuid());
                    //获取梯度
                    logisticsMmodeGradList = logsticsMmodeGradsMapper.findLogisticsMmodeGrads(params2);
                    if (logisticsMmodeGradList.size() != 0){
                        Long starTime=hwStorage.getDrksj().getTime();
                        Long endTime=now.getTime();
                        Long num=endTime-starTime;//时间戳相差的毫秒数
                        BigDecimal day = BigDecimal.valueOf(num/24/60/60/1000);
                        //获取单价
                        tdjzPrice = logisticsMmodeGradList.stream().filter(logisticsMmodeGrads1 -> day.compareTo(logisticsMmodeGrads1.getStartSection()) >= 0
                                && day.compareTo(logisticsMmodeGrads1.getEndSection()) <= 0).collect(Collectors.toList());
                        unitPrice = (tdjzPrice.size()!=0?tdjzPrice.get(0).getKg():BigDecimal.ZERO);
                        //获取仓储费=(方数*箱子数量*单价)
                        storageCharge = (hwStorage.getCube().multiply(new BigDecimal(hwStorage.getBoxnum())).multiply(unitPrice)).setScale(2, BigDecimal.ROUND_HALF_UP);
                    }
                }
                hwStorageHistory.setStorageCharge(storageCharge);
                hwStorageHistory.setUnitPrice(unitPrice);
                hwStorageHistoryMapper.insert(hwStorageHistory);
            }
        }catch (Exception e){
            e.getMessage();
        }
        return AjaxResult.success("操作成功");
    }
}
